# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
"""
Tooltip for stack descriptions.
"""
__docformat__ = 'restructuredtext en'
#_ = lambda x: x

from .window import (DigitEntry as _DigitEntry, TextEntry as _TextEnry,
                     MessageDialog as _Message, ConfirmDialog as _Confirm,
                     DoneDialog as _Finish, ProgressBar as _ProgressBar)

import ttk
import logging

LOGGER = logging.getLogger('PySolFC.ViewLib.Dialog')

from ..utillib.cache import IMAGE_CACHE
from ..pysolaudio import AUDIO_DEV
from ..settings import CONF_OPT, TITLE, PACKAGE_URL, VERSION
from . import constants as vcnst


class _AboutDialog(_Message):
    """
    About dialog.
    """

    def body(self, parent):
        """
        body(parent:Canvas) -> None

        Create body of Game About Dialog.  When timeout, set callback for
        timeout to destroy dialog. Set body text with clickable url link.
        """
        from ..utillib.misc import openURL
        self._kwargs['image'] = IMAGE_CACHE.load('logos', 'joker08_40_774')
        super(_AboutDialog, self).body(parent)
        widget = ttk.Label(parent, text=PACKAGE_URL, style='npsUri.TLabel')
        widget.pack()
        widget.bind('<1>', lambda e: openURL(PACKAGE_URL))


class _ProgressBar(_ProgressBar):
    """
    Progress dialog.
    """

    def body(self, master):
        """
        body(master:Widget) -> Widget

        Sets an image either side of a progress bar to track parent initialize
        progress.
        """
        widget = ttk.Label(master, text=self._label, style='npsLarge.TLabel')
        widget.pack()

        frame = ttk.Frame(master)
        image=IMAGE_CACHE.load('logos', 'joker07_40_774')
        LOGGER.info('image: %s', image)
        widget = ttk.Label(frame, image=image)
        widget.pack(side=vcnst.LEFT, ipadx=8, ipady=4)

        progress = ttk.Progressbar(frame, variable=self._completed, length=240)
        progress.pack(side=vcnst.LEFT, expand=True, fill=vcnst.HORZ)

        widget = ttk.Label(frame,
                           image=IMAGE_CACHE.load('logos', 'joker08_40_774'))
        widget.pack(side=vcnst.LEFT, ipadx=8, ipady=4)
        frame.pack()


_CREATE_TITLE = lambda t, p=TITLE: '{} {}'.format(p, t)


class __Dialog(object):
    __root = None
    game = None

    def connect_root(self, root):
        """
        connect_root(root:Widget) -> None
        """
        self.__root = root

    def connect_game(self, game):
        """
        connect_gameroot:Widget) -> None
        """
        self.game = game

    def confirm(self, text=None):
        """
        connect_root(text:str='Discard current game?') -> bool
        """
        game = self.game
        if game and game.is_preview:
            return True
        if CONF_OPT['confirm']:
            AUDIO_DEV.play('areyousure')
            query = _Confirm(self.__root,
                             title=_CREATE_TITLE(_('Confirmation')),
                             text=text or _('Discard current game?'))
            return query.result
        return True

    def error(self, text='', err=None):
        """
        error([text:str='', err:Error|str=None]) -> None
        """
        if isinstance(err, EnvironmentError) and err.filename is not None:
            err = '[{0.errno}] {0.strerror}: {0.filename!r}'.format(err)
        elif err is not None:
            err = '{0!s}'.format(err)
        _Message(self.__root,
                 title=_CREATE_TITLE(_('Error')),
                 text='{}\n{}'.format(text, err),
                 bitmap='error')

    def info(self, text=''):
        """
        info([text:str='']) -> None
        """
        _Message(self.__root,
                 title=_CREATE_TITLE(_('Info')),
                 text=text)

    def select(self, text='', value=''):
        """
        select([text:str='', value:str='']) -> int
        """
        entry = _DigitEntry(self.__root,
                            title=_CREATE_TITLE(_('Select')),
                            label=text, value=value)
        return entry.result

    def warning(self, text=''):
        """
        warning([text:str='']) -> None
        """
        _Message(self.__root,
                 title=_CREATE_TITLE(_('Warning')),
                 text=text, bitmap='warning')

    def comment(self, name, number):
        """
        comment(name:str, number:int) -> None
        """
        if self.game is None:
            return
        from os import linesep
        title = '{0} {1} #{2}'.format(_('Comments for'), name, number)
        curr_text = NOTE_DB.get(name) or '{0}{1}{1}'.format(title, linesep)
        query = EditTextDialog(self.__root,
                               title=_CREATE_TITLE(_('Comment')),
                               label=title, value=curr_text)
        text = query.result.strip()
        if text != curr_text.strip():
            NOTE_DB[name] = text + linesep

    def progress(self, step=.5):
        """
        progress(step:float|int=.5) -> Progress

        Create a dialog sans decoration that minimizes the game program while it
        shows a completion progress bar to as the necessary settings are loaded for
        the next game.
        """
        text = _(u'{0}, version {1}').format(TITLE, VERSION)
        progress = _ProgressBar(self.__root, title=text)
        progress.update(step=step)
        return progress

    def finish_player(self, rank='', status=0):
        """
        finish([rank:str='', status:int=0]) -> str
        """
        game = self.game
        text = [_('Too bad. '), _('Good job. '), _('Great success. ')][status]
        # c) Add current info
        stat = p_.ungettext('Time was {} for {} move.',
                            'Time was {} for {} moves.',
                           game.move_index).format(game._timer, game.move_index)
        AUDIO_DEV.play('game{}'.format(['finished', 'won', 'perfect'][status]),
                       priority=1000)  # lost not included
        kwargs = {'text': _('{} Game finished. {} {}').format(text, stat, rank)}
        if status in [1, 2]:
            kwargs['image'] = IMAGE_CACHE.load('logos', 'joker11_100_774')
        return _Finish(self.__root,
                        title=_CREATE_TITLE(_('Game finished')),
                        **kwargs)

    def finish_demo(self, moves, winner):
        game = self.game
        stat = p_.ungettext('Time was {} for {} move.',
                                'Time was {} for {} moves.',
                           game.move_index).format(game._timer, game.move_index)
        if not moves:
            text = [_('Too bad. '), _('Great success. ')][winner]
            sample = ['autopilotlost', 'autopilotwon'][winner]
            timeout = 50000
        else:
            text = ''
            sample = None
            timeout = 1000
        AUDIO_DEV.play(sample, priority=1000)
        kwargs = {'text': _('{} Demo finished. {}').format(text, stat)}
        return _Finish(self.__root, title=_CREATE_TITLE(_('Demo finished')),
                       timeout=timeout, **kwargs)

    def about(self, timeout=0):
        """
        about(timeout:int=0) -> str

        Create a dialog that includes info about the game program, its author and
        its license. Includes an optional timeout that destroys the dialog after
        the timeout value in milliseconds. Sets the dialog text and calls Dialog.
        """
        AUDIO_DEV.play('about')

        text = _(
            u'{0}, version {1}\n\n'
            u'An extensive collection of solitaire games '
            u'based on {2} and coded in python.\n\n'
            u'  · © 1998-2003 Markus Oberhumer\n'
            u'  · © 2003 Mt. Hood Playing Card Co\n'
            u'  · © 2005-2010 Skomoroh\n'
            u'  · © 2010-2013 Jeremy Austin-Bardo\n\n'
            u'This program is free software: you can '
            u'redistribute it and/or modify it under the '
            u'terms of the GNU General Public License as '
            u'published by the Free Software Foundation, '
            u'version 3 of the License.').format(TITLE, VERSION, 'PySol')

        title = _("About {}").format(TITLE, timeout)

        dialog = _AboutDialog(self.__root, title=title, text=text,
                              timeout=timeout)
        if dialog.result == 'credits':
            self._credit()
        return dialog.state

    def _credit(self):
        """
        credit() -> None

        Create a dialog that gives credit to those that made the game program
        possible. Sets the text and calls Message.
        """
        if sound:
            AUDIO_DEV.play('credits')

        text = _(
            u'{0} Credits and Thanks\n\n'
            u'  · Markus Oberhumer for coding the original '
            u'    code for PySol.\n'
            u'  · Skomorroh for resuming and furthering the '
            u'    code with PySol Fan Club edition.\n'
            u'  · T. Kirk for his contribution to the games '
            u'    and cardsets.\n\n'
            u'Especially the wider Free Software and Python '
            u'communities for their contributions that make '
            u'software like this possible.').format(TITLE)

        return _Message(parent, title=_("Credits"), message=text,
                         image=IMAGE_CACHE.load('logos', 'joker07_50_774'),
                         side='right')

Dialog = __Dialog()